package com.tanhua.dubbo.server.api;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.mongodb.client.result.DeleteResult;
import com.tanhua.dubbo.server.pojo.*;
import com.tanhua.dubbo.server.service.IdService;
import com.tanhua.dubbo.server.vo.PageInfo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service(version = "1.0.0")
public class QuanziApiImpl implements QuanZiApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    // 发布动态
    // 获取publish的用户id,没有用户则为错误数据,返回false
    // 正常数据则继续执行,设置动态和相册的创建时间,然后将动态写入到好友的时间线
    @Override
    public String savePublish(Publish publish) {
        if (publish.getUserId() == null) {
            return null;
        }

        try {
            publish.setCreated(System.currentTimeMillis());// 设置创建时间
            publish.setId(ObjectId.get());// 设置发布id
            publish.setPid(idService.getPublishId("publish",publish.getId().toHexString()));

            mongoTemplate.save(publish);// 保存此发布

            Album album = new Album();// 创建相册对象
            album.setPublishId(publish.getId());// 设置指定发布的id
            album.setCreated(System.currentTimeMillis());// 设置创建时间
            album.setId(ObjectId.get());// 设置相册id

            mongoTemplate.save(album, "quanzi_album_" + publish.getUserId());// 保存

            // 查询好友列表
            Query query = Query.query(Criteria.where("userId").is(publish.getUserId()));
            List<Users> usersList = mongoTemplate.find(query, Users.class);

            // 遍历好友列表写入好友的时间线表[TimeLine]
            for (Users users : usersList) {
                TimeLine timeLine = new TimeLine();// 创建时间线对象
                timeLine.setPublishId(publish.getId());// 设置发布id
                timeLine.setId(ObjectId.get());// 设置时间线id
                timeLine.setUserId(publish.getUserId());// 设置用户id
                timeLine.setDate(System.currentTimeMillis());// 设置时间

                mongoTemplate.save(timeLine, "quanzi_time_line_" + users.getFriendId());
            }
            return publish.getId().toHexString();
            // 没出异常则执行成功,出现异常则捕获并跳过剩余代码,执行下面代码
        } catch (Exception e) {
            e.getStackTrace();
            // 出错应该回滚事务,暂不实现,MongoDB非集群不支持事务
        }

        return null;
    }

    @Override
    public PageInfo<Publish> queryPublishList(Long userId, Integer page, Integer pageSize) {

        // 判断是否有用户id,没有id则为查询推荐动态列表,有则为查询好友动态
        String tableName = "quanzi_time_line_";
        if (userId == null) {
            tableName += "recommend";
        } else {
            tableName += userId;
        }

        // 查询时间线
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("date")));
        Query query = new Query().with(pageRequest);
        List<TimeLine> timeLineList = mongoTemplate.find(query, TimeLine.class, tableName);

        // 拿到所有时间线对应的publish的id
        List<ObjectId> idList = new ArrayList<>();
        for (TimeLine timeLine : timeLineList) {
            idList.add(timeLine.getPublishId());
        }
        // 查询所有publish
        Query queryPublish = Query.query(Criteria.where("id").in(idList)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = mongoTemplate.find(queryPublish, Publish.class);

        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(publishList);// 传递数据
        pageInfo.setTotal(0); //不提供总数
        return pageInfo;

    }

    @Override
    public boolean saveLikeComment(Long userId, String publishId) {
        // 查询是否已经点赞,防止多次点赞
        Criteria criteria = Criteria.where("userId").is(userId)
                .and("publishId").is(new ObjectId(publishId))
                .and("commentType").is(1);
        long count = mongoTemplate.count(Query.query(criteria), Comment.class);
        if (count > 1) {
            return false;
        }
        // 保存点赞
        return saveComment(userId, publishId, 1, null);
    }

    @Override
    public boolean removeComment(Long userId, String publishId, Integer commentType) {
        // 根据条件删除
        Query query = Query.query(Criteria
                .where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId)
                .and("commentType").is(commentType));
        DeleteResult remove = this.mongoTemplate.remove(query, Comment.class);
        return remove.getDeletedCount() > 0;
    }

    @Override
    public boolean saveLoveComment(Long userId, String publishId) {
        Criteria criteria = Criteria.where("userId").is(userId)
                .and("publishId").is(new ObjectId(publishId))
                .and("commentType").is(3);
        long count = mongoTemplate.count(Query.query(criteria), Comment.class);
        if (count > 1) {
            return false;
        }
        return saveComment(userId, publishId, 3, null);
    }

    @Override
    public boolean saveComment(Long userId, String publishId, Integer type, String content) {

        try {
            Comment comment = new Comment();
            comment.setContent(content);
            comment.setIsParent(true);
            comment.setCommentType(type);
            comment.setPublishId(new ObjectId(publishId));
            comment.setUserId(userId);
            comment.setId(ObjectId.get());
            comment.setCreated(System.currentTimeMillis());

            // 设置发布人的id
            Publish publish = this.mongoTemplate.findById(comment.getPublishId(), Publish.class);
            if (null != publish) {
                comment.setPublishUserId(publish.getUserId());
            } else {
                Video video = this.mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (null != video) {
                    comment.setPublishUserId(video.getUserId());
                }
            }

            this.mongoTemplate.save(comment);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    @Override
    public Long queryCommentCount(String publishId, Integer type) {
        // 查询点赞/喜欢/评论的总条数
        Query query = Query.query(Criteria.where("publishId").is(publishId).and("commentType").is(type));
        return this.mongoTemplate.count(query, Comment.class);
    }

    @Override
    public Publish queryPublishById(String publishId) {
        return mongoTemplate.findById(publishId, Publish.class);
    }

    @Override
    public PageInfo<Comment> queryCommentList(String publishId, Integer page, Integer pageSize) {
        // 获取评论列表
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.asc("created")));
        Query query = Query.query(Criteria
                .where("publishId").is(new ObjectId(publishId))
                .and("commentType").is(2)).with(pageRequest);
        List<Comment> commentList = mongoTemplate.find(query, Comment.class);

        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(commentList);

        return pageInfo;
    }

    @Override
    public PageInfo<Comment> queryCommentListByUser(Long userId, int type, Integer page, Integer pageSize) {
        // 获取评论列表
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query(Criteria
                .where("publishUserId").is(userId)
                .and("commentType").is(type)).with(pageRequest);

        List<Comment> commentList = this.mongoTemplate.find(query, Comment.class);

        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(commentList);
        pageInfo.setTotal(0); //不提供总数
        return pageInfo;
    }

    @Override
    public List<Publish> queryPublishByPids(List<Long> pidList) {
        return mongoTemplate.find(Query.query(Criteria.where("pid").in(pidList)),Publish.class);
    }

    @Override
    public PageInfo<Publish> queryAlbumList(Long userId, Integer page, Integer pageSize) {

        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(0); //不提供总数

        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query().with(pageRequest);
        List<Album> albumList = this.mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);

        if(CollectionUtils.isEmpty(albumList)){
            return pageInfo;
        }


        List<ObjectId> publishIds = new ArrayList<>();
        for (Album album : albumList) {
            publishIds.add(album.getPublishId());
        }

        //查询发布信息
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);

        pageInfo.setRecords(publishList);

        return pageInfo;
    }

}
